package xgenerator.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * Title:记号，表示法，注释，记法工具类
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: Copyright (c) 2012
 * </p>
 * <p>
 * Company: liss
 * </p>
 * @author <a href="mailto:shushanlee@msn.com">liss</a>
 * @version 1.0
 * @see 
 * @since   1.0
 */
public class NotationUtils {
	
	/**
	 * 默认表示法分割符
	 */
	public static String DEFAULT_NOTATION_SEPARATOR = "_";
	
	
	/**
	 * <p>
	 * Title：使字符串的首字母大写
	 * </p>
	 * <p>
	 * Description：(capital letters(block letters)：大写字母、：小写字母)，或 initials(第一个字母) in capitals
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#initCap(String)
	 * @param name
	 * @return
	 */
	public static String capFirst(String name) {
		if (StringUtils.isBlank(name)) {
			return name;
		}
		char firstChar = name.charAt(0);
		String firstUppperCase = (String.valueOf(firstChar)).toUpperCase();
		String rest = name.substring(1, name.length());
		return (firstUppperCase + rest);
	}

	/**
	 * <p>
	 * Title：使字符串的首字母小写
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#initSmall(String)
	 * @param name
	 * @return
	 */
	public static String smallFirst(String name) {
		if (StringUtils.isBlank(name)) {
			return name;
		}
		char firstChar = name.charAt(0);
		String firstLowerCase = (String.valueOf(firstChar)).toLowerCase();
		String rest = name.substring(1, name.length());
		return (firstLowerCase + rest);
	}

	/**
	 * <p>
	 * Title：使字符串的首字母大写
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#capFirst(String)
	 * @param name
	 * @return
	 */
	public static String initCap(String name) {
		return capFirst(name);
	}

	/**
	 * <p>
	 * Title：使字符串的首字母小写
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#smallFirst(String)
	 * @param name
	 * @return
	 */
	public static String initSmall(String name) {
		return smallFirst(name);
	}

	/**
	 * <p>
	 * Title：将字符串Array中的字符串连接为LowerCamelCase
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param strArray
	 * @return 
	 */
	private static String splitJointLowerCamelCase(String[] strArray) {
		return smallFirst(splitJointUpperCamelCase(strArray));
	}

	/**
	 * <p>
	 * Title：将字符串Array中的字符串连接为UpperCamelCase
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param strArray
	 * @return
	 */
	private static String splitJointUpperCamelCase(String[] strArray) {
		if (null == strArray) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		for (String oneString : strArray) {
			if (StringUtils.isNotBlank(oneString)) {
				sb.append(capFirst(oneString.toLowerCase()));
			}
		}
		return sb.toString();
	}

	/**
	 * <p>
	 * Title：将字符串Array中的字符串连接为Underscore
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param strArray
	 * @return
	 */
	private static String splitJointUnderscore(String[] strArray) {
		if (null == strArray) {
			return null;
		}
		StringBuilder sb = new StringBuilder();
		boolean firstFlag = true;
		for (String oneString : strArray) {
			if (StringUtils.isNotBlank(oneString)) {
				if (firstFlag) {
					firstFlag = false;
					sb.append(oneString.toLowerCase());
				} else {
					sb.append(DEFAULT_NOTATION_SEPARATOR + oneString.toLowerCase());
				}
			}
		}
		return sb.toString();
	}
	
	/**
	 * <p>
	 * Title：name的UpperCamelCase表示
	 * </p>
	 * <p>
	 * Description：CamelCase (or camel case), also known as medial capitals, is the practice of writing compound words or phrases in which the elements are joined without spaces, with each
	 * element's initial letter capitalized within the compound and the first letter either upper or lower case—as in "LaBelle", "BackColor", "iPod", or "GaGa". The name comes from the uppercase
	 * "bumps" in the middle of the compound word, suggestive of the humps of a camel. The practice is known by many other names, the most common of which is Pascal case for upper camel case.
	 * </p>
	 * 
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String upperCamelCase(String name, final String separator, final String filterPrefix, final String filterSuffer) {
		if (StringUtils.isBlank(name)) {
			return name;
		}
		if (null == separator) {
			throw new IllegalArgumentException("splitRegex is null");
		}
		if (StringUtils.isNotBlank(filterPrefix)) {
			if(name.startsWith(filterPrefix)) {
				name = name.replaceFirst(filterPrefix, "");
			}
		}
		if (StringUtils.isNotBlank(filterSuffer)) {
			if(name.endsWith(filterSuffer)) {
				name = name.substring(0, name.lastIndexOf(filterSuffer));
			}
		}
		String[] splitedNamesArray = name.split(separator);
		return splitJointUpperCamelCase(splitedNamesArray);
	}
	
	/**
	 * <p>
	 * Title：name的UpperCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String upperCamelCase(String name, String separator, final String filterPrefix) {
		return upperCamelCase(name, separator, null, null);
	}

	/**
	 * <p>
	 * Title：name的UpperCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @return
	 */
	public static String upperCamelCase(String name, String separator) {
		return upperCamelCase(name, separator, null);
	}

	/**
	 * <p>
	 * Title：name的UpperCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @return
	 */
	public static String upperCamelCase(String name) {
		return upperCamelCase(name, DEFAULT_NOTATION_SEPARATOR);
	}

	/**
	 * <p>
	 * Title：name的LowerCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String lowerCamelCase(String name, String separator, final String filterPrefix, final String filterSuffer) {
		return smallFirst(upperCamelCase(name, separator, filterPrefix, filterSuffer));
	}
	
	/**
	 * <p>
	 * Title：name的LowerCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String lowerCamelCase(String name, String separator, final String filterPrefix) {
		return lowerCamelCase(name, separator, null, null);
	}
	
	/**
	 * <p>
	 * Title：name的LowerCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @param separator
	 * @return
	 */
	public static String lowerCamelCase(String name, String separator) {
		return lowerCamelCase(name, separator, null);
	}

	/**
	 * <p>
	 * Title：name的LowerCamelCase表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @return
	 */
	public static String lowerCamelCase(String name) {
		return lowerCamelCase(name, DEFAULT_NOTATION_SEPARATOR);
	}

	/**
	 * <p>
	 * Title：Pascal Notation
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#upperCamelCase(String, String, String)
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String pascalNotation(String name, String separator, final String filterPrefix, final String filterSuffer) {
		return upperCamelCase(name, separator, filterPrefix, filterSuffer);
	}
	
	/**
	 * <p>
	 * Title：Pascal Notation
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#upperCamelCase(String, String, String)
	 * @param name
	 * @param separator
	 * @param filterPrefix
	 * @return
	 */
	public static String pascalNotation(String name, String separator, final String filterPrefix) {
		return upperCamelCase(name, separator, filterPrefix);
	}
	
	/**
	 * <p>
	 * Title：Pascal Notation
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#upperCamelCase(String, String)
	 * @param name
	 * @param separator
	 * @return
	 */
	public static String pascalNotation(String name, String separator) {
		return upperCamelCase(name, separator);
	}

	/**
	 * <p>
	 * Title：Pascal Notation
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @see xgenerator.util.NotationUtils#upperCamelCase(String)
	 * @param name
	 * @return
	 */
	public static String pascalNotation(String name) {
		return upperCamelCase(name);
	}

	/**
	 * <p>
	 * Title：name的Underscore表示
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @return
	 */
	public static String underscore(String name) {
		if (StringUtils.isBlank(name)) {
			return name;
		}
		return name.toLowerCase();
	}
	
	/**
	 * <p>
	 * Title：StudlyCaps——单词当中的字母随机或按某些规律大小写混排，这种写法没有什么“讲究”，纯粹是增加了阅读和输入的难度
	 * </p>
	 * <p>
	 * Description：StudlyCaps (or perhaps StUdLyCaPs, also known as StickyCaps) is a variation of CamelCase in which the individual letters in a word (or words) are capitalized and not capitalized,
	 * either at random or in some pattern.
	 * </p>
	 * 
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @return
	 */
	public static String studlyCaps(String name) {
		if (StringUtils.isBlank(name)) {
			return name;
		}
		return DEFAULT_NOTATION_SEPARATOR + lowerCamelCase(name);
	}
	
	/**
	 * <p>
	 * Title：将Java对象名称（每个单词的头字母大写）按照 数据库命名的习惯进行格式化 格式化后的数据为小写字母，并且使用下划线分割命名单词
	 * </p>
	 * <p>
	 * Description：例如：employeeInfo 经过格式化之后变为 employee_info
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name Java对象名称
	 * @return
	 */
	public static String wordFormat4DBLowerCase(String name) {
		if (null == name) {
			return null;
		}
		Pattern p = Pattern.compile("[A-Z]");
		Matcher m = p.matcher(name);
		StringBuffer sb = new StringBuffer();

		for (int i = 0; m.find(); i++) {
			if (0 == i) {
				m.appendReplacement(sb, m.group());
			} else {
				m.appendReplacement(sb, "_" + m.group());
			}
		}

		return m.appendTail(sb).toString().toLowerCase();
	}
	
	/**
	 * <p>
	 * Title：将Java对象名称（每个单词的头字母大写）按照 数据库命名的习惯进行格式化 格式化后的数据为大写字母，并且使用下划线分割命名单词
	 * </p>
	 * <p>
	 * Description：例如：employeeInfo 经过格式化之后变为 EMPLOYEE_INFO
	 * </p>
	 * @author <a href="mailto:shushanlee@msn.com">liss</a>
	 * @param name
	 * @return
	 */
	public static String wordFormat4DBUpperCase(String name) {
		if (null == name) {
			return null;
		}
		return wordFormat4DBLowerCase(name).toUpperCase();
	}
	
	/**
	 * <p>
	 * Title：测试方法
	 * </p>
	 * <p>
	 * Description：
	 * </p>
	 * @param args
	 */
	public static void main(String[] args) {
		String ss = "aa_aBBccFFF123";
		System.out.println("capFirst=" + capFirst(ss));
		System.out.println("smallFirst=" + smallFirst(ss));
		System.out.println("studlyCaps=" + studlyCaps(ss));

		String[] strArray = { null, " ", "aaaaaaaaaaaaa", null, "AAAbbCCdd", "cccYY" };
		System.out.println("concatUpperCamelCase=" + splitJointUpperCamelCase(strArray));
		System.out.println("concatLowerCamelCase=" + splitJointLowerCamelCase(strArray));
		System.out.println("concatUnderscore=" + splitJointUnderscore(strArray));

		String tableName = "aaa_BB_cc_FF_F_123";
		System.out.println("表名->lowerCamelCase=" + lowerCamelCase(tableName));
		System.out.println("表名->upperCamelCase=" + upperCamelCase(tableName));

		String fieldName = "aaa_BB_cc_FF_F_123";
		System.out.println("字段名->lowerCamelCase=" + lowerCamelCase(fieldName));
		System.out.println("字段名->underscore=" + underscore(fieldName));
		System.out.println("字段名->studlyCaps=" + studlyCaps(fieldName));
		
		String target = "EmployeeInfoUserName";
		String resultLowerCase = NotationUtils.wordFormat4DBLowerCase(target);
		String resultUpperCase = NotationUtils.wordFormat4DBUpperCase(target);
		System.out.println(resultLowerCase);
		System.out.println(resultUpperCase);
	}

}
